// process.cpp
// Created by fyniny on 12/23/18.
//
#include "process.h"
#include "dispatchprocess.h"
#include "spooling.h"
process::process(int max_output,PCB pcb):Base(max_output,&pcb) {}
void process::run(void* dispath) {
    auto* dis = (DispathProcess*)dispath;
    Base& output = *(dis->getInstance(process_id::spooling));
    // 若输出为空时才随机生成
    if (buffer == nullptr) {
        buffer = new Buffer;
        req = new ReqBlock;
        int i = 0;
        int ch;
        // 减2是因为空字符占一位并且最后一位是0
        while (0 != (ch = (int)rand() % 10) && i < BUFFER::buf_size - 1)
        {
            if (i == BUFFER::buf_size - 2) {
                break;
            }
            i++;
            *buffer << ch;

        }
        (*buffer) << 0;
        *req = { getProcessID(),i + 1 };
    }
    // 判断假脱机是否满输出队列,若满则阻塞自己
    if (output.getProcessStatus() != PROCESS_WAIT_FULL_OUTPUT_BLOCK)
    {
        // request 函数中包含唤醒spooling进程
        if (PROCESS_WAIT_FULL_OUTPUT_BLOCK == output.request(*req, *buffer)) {
            SHOW_WAKE;
            setProcessStatus(PROCESS_WAIT_FULL_OUTPUT_BLOCK);
            return;
        }
        this->output(1);
        // 输出成功之后清空输出缓冲区
        delete buffer;
        delete req;
        buffer = nullptr;
        req = nullptr;
    }
    else
    {
        SHOW_WAKE;
        setProcessStatus(PROCESS_WAIT_FULL_OUTPUT_BLOCK);
    }
}
